﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApAPPRotationLimitsGlobalManager
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.AutomaticPathPlanner;
using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Timers;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands;

public class CApAPPRotationLimitsGlobalManager
{
  private CApAPPLimitsViewModel m_limitViewModel;

  public CApAPPLimitsViewModel LimitsViewModel
  {
    get => this.m_limitViewModel;
    set => this.m_limitViewModel = value;
  }

  public List<CApAPPObjectFlowTask> ObjectFlowTaskList { get; set; }

  public void ComputeRotationRangeForAxis(
    AxisType axisType,
    CApAPPWaypoint startPoint,
    List<CApAPPWaypoint> wpOutSideLimits,
    double currentMinValue,
    double currentMaxValue,
    out double minRange,
    out double maxRange)
  {
    minRange = 0.0;
    maxRange = 0.0;
    double num = 0.0;
    TxTransformation absoluteLocation1 = startPoint.SimulatedApproachLocation.AbsoluteLocation;
    foreach (CApAPPWaypoint wpOutSideLimit in wpOutSideLimits)
    {
      TxTransformation absoluteLocation2 = wpOutSideLimit.SimulatedApproachLocation.AbsoluteLocation;
      TxVector rotationRpyZyx = TxTransformation.op_Multiply(absoluteLocation1.Inverse, absoluteLocation2).RotationRPY_ZYX;
      bool flag = false;
      switch (axisType)
      {
        case AxisType.AXIS_RX:
          num = rotationRpyZyx.X;
          flag = this.LimitsViewModel.RxDofStatus == 2;
          break;
        case AxisType.AXIS_RY:
          num = rotationRpyZyx.Y;
          flag = this.LimitsViewModel.RyDofStatus == 2;
          break;
        case AxisType.AXIS_RZ:
          num = rotationRpyZyx.Z;
          flag = this.LimitsViewModel.RzDofStatus == 2;
          break;
      }
      if (flag)
      {
        currentMaxValue = 0.0;
        currentMinValue = 0.0;
      }
      if (num < currentMinValue && num < minRange)
        minRange = num;
      if (num > currentMaxValue && num > maxRange)
        maxRange = num;
    }
  }

  public bool AreRotationLimitsValidForTask(
    CApAPPObjectFlowTask task,
    out string errorMessage,
    out List<CApAPPWaypoint> waypointsWithRotationLimitError)
  {
    bool flag1 = true;
    errorMessage = "";
    waypointsWithRotationLimitError = new List<CApAPPWaypoint>();
    if (task != null)
    {
      List<CApAPPWaypoint> waypointsWithRotationLimitError1 = (List<CApAPPWaypoint>) null;
      waypointsWithRotationLimitError = new List<CApAPPWaypoint>();
      double minRange = 0.0;
      double maxRange = 0.0;
      KiAppLimitsEx limits = task.Limits;
      bool flag2 = task.AreRotationLimitsValid(AxisType.AXIS_RX, out waypointsWithRotationLimitError1);
      double num;
      if (!flag2)
      {
        waypointsWithRotationLimitError = waypointsWithRotationLimitError1;
        this.ComputeRotationRangeForAxis(AxisType.AXIS_RX, task.Waypoint(0), waypointsWithRotationLimitError1, limits.RxMinValue, limits.RxMaxValue, out minRange, out maxRange);
        ref string local = ref errorMessage;
        string rangeDescription = CApAPPMainWindowStringTable.PathPlanningRotationRangeDescription;
        string str1 = (minRange / TxApplication.Options.Units.AngularMultiplier).ToString(CApCableUtility.NumericLinearFormat);
        num = maxRange / TxApplication.Options.Units.AngularMultiplier;
        string str2 = num.ToString(CApCableUtility.NumericLinearFormat);
        string str3 = "Rx " + string.Format(rangeDescription, (object) str1, (object) str2);
        local = str3;
      }
      bool flag3 = task.AreRotationLimitsValid(AxisType.AXIS_RY, out waypointsWithRotationLimitError1);
      if (!flag3)
      {
        waypointsWithRotationLimitError.InsertRange(waypointsWithRotationLimitError.Count, (IEnumerable<CApAPPWaypoint>) waypointsWithRotationLimitError1);
        this.ComputeRotationRangeForAxis(AxisType.AXIS_RY, task.Waypoint(0), waypointsWithRotationLimitError1, limits.RyMinValue, limits.RyMaxValue, out minRange, out maxRange);
        if (errorMessage != "")
          errorMessage += ", ";
        ref string local = ref errorMessage;
        string str4 = errorMessage;
        string rangeDescription = CApAPPMainWindowStringTable.PathPlanningRotationRangeDescription;
        num = minRange / TxApplication.Options.Units.AngularMultiplier;
        string str5 = num.ToString(CApCableUtility.NumericLinearFormat);
        num = maxRange / TxApplication.Options.Units.AngularMultiplier;
        string str6 = num.ToString(CApCableUtility.NumericLinearFormat);
        string str7 = string.Format(rangeDescription, (object) str5, (object) str6);
        string str8 = $"{str4}Ry {str7}";
        local = str8;
      }
      bool flag4 = task.AreRotationLimitsValid(AxisType.AXIS_RZ, out waypointsWithRotationLimitError1);
      if (!flag4)
      {
        waypointsWithRotationLimitError.InsertRange(waypointsWithRotationLimitError.Count, (IEnumerable<CApAPPWaypoint>) waypointsWithRotationLimitError1);
        this.ComputeRotationRangeForAxis(AxisType.AXIS_RZ, task.Waypoint(0), waypointsWithRotationLimitError1, limits.RzMinValue, limits.RzMaxValue, out minRange, out maxRange);
        if (errorMessage != "")
          errorMessage += ", ";
        ref string local = ref errorMessage;
        string str9 = errorMessage;
        string rangeDescription = CApAPPMainWindowStringTable.PathPlanningRotationRangeDescription;
        num = minRange / TxApplication.Options.Units.AngularMultiplier;
        string str10 = num.ToString(CApCableUtility.NumericLinearFormat);
        num = maxRange / TxApplication.Options.Units.AngularMultiplier;
        string str11 = num.ToString(CApCableUtility.NumericLinearFormat);
        string str12 = string.Format(rangeDescription, (object) str10, (object) str11);
        string str13 = $"{str9}Rz {str12}";
        local = str13;
      }
      flag1 = flag2 & flag3 & flag4;
    }
    return flag1;
  }

  public void Restore()
  {
    if (this.ObjectFlowTaskList == null)
      return;
    foreach (CApAPPObjectFlowTask objectFlowTask in this.ObjectFlowTaskList)
      this.RestoreDefaultLimitsForTask(objectFlowTask);
  }

  public void RestoreDefaultLimitsForTask(CApAPPObjectFlowTask objectFlowTask)
  {
    KiAppLimitsEx limits = (objectFlowTask.KiTask as KiAppObjectFlowTaskEx).GetLimits();
    limits.RxMinValue = -1.0 * Math.PI;
    limits.RxMaxValue = Math.PI;
    limits.RyMinValue = -1.0 * Math.PI;
    limits.RyMaxValue = Math.PI;
    limits.RzMinValue = -1.0 * Math.PI;
    limits.RzMaxValue = Math.PI;
    limits.RxDofStatus = (KiAppLimitDofStatus) 0;
    limits.RyDofStatus = (KiAppLimitDofStatus) 0;
    limits.RzDofStatus = (KiAppLimitDofStatus) 0;
  }

  public void AnimateRotationRange(CApAPPObjectFlowTask task, AxisType axisType)
  {
    if (task == null)
      return;
    TxTransformation absoluteLocation1 = (task.Operation as TxObjectFlowOperation).GripFrame.AbsoluteLocation;
    TxObjectList simulatedObjects = task.Operation.SimulatedObjects;
    if (((Collection<ITxObject>) simulatedObjects).Count == 0)
      return;
    ITxLocatableObject locatableObject = ((IEnumerable<ITxObject>) simulatedObjects).ElementAt<ITxObject>(0) as ITxLocatableObject;
    TxTransformation absoluteLocation2 = locatableObject.AbsoluteLocation;
    TxTransformation relativeGripFrame = TxTransformation.op_Multiply(locatableObject.AbsoluteLocation.Inverse, absoluteLocation1);
    TxTransformation absoluteLocation3 = task.Waypoint(0).SimulatedApproachLocation.AbsoluteLocation;
    locatableObject.AbsoluteLocation = TxTransformation.op_Multiply(absoluteLocation3, relativeGripFrame.Inverse);
    TxApplication.RefreshDisplay();
    this.AnimateRotationRange(locatableObject.AbsoluteLocation, locatableObject, axisType, relativeGripFrame);
    locatableObject.AbsoluteLocation = absoluteLocation2;
    TxApplication.RefreshDisplay();
  }

  public void AnimateRotationRange(
    TxTransformation absoluteStartLocation,
    ITxLocatableObject locatableObject,
    AxisType axisType,
    TxTransformation relativeGripFrame)
  {
    if (locatableObject == null)
      return;
    double maxValue1 = 0.0;
    double maxValue2 = 0.0;
    switch (axisType)
    {
      case AxisType.AXIS_RX:
        maxValue1 = this.LimitsViewModel.RxMinValue;
        maxValue2 = this.LimitsViewModel.RxMaxValue;
        break;
      case AxisType.AXIS_RY:
        maxValue1 = this.LimitsViewModel.RyMinValue;
        maxValue2 = this.LimitsViewModel.RyMaxValue;
        break;
      case AxisType.AXIS_RZ:
        maxValue1 = this.LimitsViewModel.RzMinValue;
        maxValue2 = this.LimitsViewModel.RzMaxValue;
        break;
    }
    this.DoAnimateRotationRange(locatableObject, axisType, relativeGripFrame, maxValue1);
    this.DoAnimateRotationRange(locatableObject, axisType, relativeGripFrame, -maxValue1);
    this.DoAnimateRotationRange(locatableObject, axisType, relativeGripFrame, maxValue2);
    this.DoAnimateRotationRange(locatableObject, axisType, relativeGripFrame, -maxValue2);
  }

  public void DoAnimateRotationRange(
    ITxLocatableObject locatableObject,
    AxisType axisType,
    TxTransformation relativeGripFrame,
    double maxValue)
  {
    TxTransformation txTransformation = (TxTransformation) null;
    new Timer().Start();
    Stopwatch stopwatch = new Stopwatch();
    long num1 = 500;
    long num2 = 0;
    stopwatch.Start();
    double num3 = 0.0;
    while (num2 < num1)
    {
      num2 = stopwatch.ElapsedMilliseconds;
      double num4 = (num2 >= num1 ? maxValue : (double) num2 * maxValue / (double) num1) - num3;
      switch (axisType)
      {
        case AxisType.AXIS_RX:
          txTransformation = new TxTransformation(new TxVector(num4, 0.0, 0.0), (TxTransformation.TxRotationType) 1);
          break;
        case AxisType.AXIS_RY:
          txTransformation = new TxTransformation(new TxVector(0.0, num4, 0.0), (TxTransformation.TxRotationType) 1);
          break;
        case AxisType.AXIS_RZ:
          txTransformation = new TxTransformation(new TxVector(0.0, 0.0, num4), (TxTransformation.TxRotationType) 1);
          break;
      }
      locatableObject.AbsoluteLocation = TxTransformation.op_Multiply(TxTransformation.op_Multiply(TxTransformation.op_Multiply(locatableObject.AbsoluteLocation, relativeGripFrame), txTransformation), relativeGripFrame.Inverse);
      TxApplication.RefreshDisplay();
      num3 += num4;
    }
    stopwatch.Stop();
  }
}
